from datetime import date, datetime
from typing import Tuple, List, Any

from extract.extractor import Extractor
from src.config.parameter import Parameter
from src.handle.account_info import AccountInfo
from src.handle.acquirer import Acquirer
from src.tools.retry import PrivateRetry
from src.tools.temporary import timestamp


class Account(Acquirer):
    post_api = "https://www.douyin.com/aweme/v1/web/aweme/post/"
    favorite_api = "https://www.douyin.com/aweme/v1/web/aweme/favorite/"

    def __init__(
            self,
            params: Parameter,
            sec_user_id: str,
            tab="post",
            earliest="",
            latest="",
            max_cursor: int = 0,
            pages: int = None):
        super().__init__(params)
        self.params = params
        self.sec_user_id = sec_user_id
        self.max_cursor = max_cursor
        self.api, self.favorite, self.pages = self.check_type(
            tab, pages or 99999)
        self.earliest, self.latest = self.check_date(earliest, latest)
        self.info = AccountInfo(params, sec_user_id)

    def check_type(self, tab: str, pages: int) -> Tuple[str, bool, int]:
        if tab=="favorite":
            return self.favorite_api, True, pages
        elif tab!="post":
            print(f"tab 参数 {tab} 设置错误，程序将使用默认值: post")
        return self.post_api, False, pages

    def check_date(self, start: str, end: str) -> Tuple[date, date]:
        return self.check_earliest(start), self.check_latest(end)

    def check_earliest(self, date_: str) -> date:
        if not date_:
            return date(2016, 9, 20)
        try:
            earliest = datetime.strptime(
                date_, "%Y/%m/%d")
            print(f"作品最早发布日期: {date_}")
            return earliest.date()
        except ValueError:
            print(f"作品最早发布日期 {date_} 无效")
            return date(2016, 9, 20)

    def check_latest(self, date_: str) -> date:
        if not date_:
            return date.today()
        try:
            latest = datetime.strptime(date_, "%Y/%m/%d").date()
            print(f"作品最晚发布日期: {date_}")
            return latest
        except ValueError:
            print(f"作品最晚发布日期无效 {date_}")
            return date.today()

    def run(self) -> Any:
        return self.get_account_data(self.api)

    def favorite_mode(self):
        if not self.favorite:
            return
        info = Extractor(self.params).get_user_info(self.info.run())
        if self.sec_user_id!=(s := info.get("sec_uid")):
            print(f"sec_user_id {self.sec_user_id} 与 {s} 不一致")
            self.generate_temp_data()
        else:
            self.response.append({"author": info})

    def early_stop(self):
        """如果获取数据的发布日期已经早于限制日期，就不需要再获取下一页的数据了"""
        if not self.favorite and self.earliest > datetime.fromtimestamp(
                max(self.cursor / 1000, 0)).date():
            self.finished = True


    @PrivateRetry.retry
    def get_account_data(self, api: str):
        if self.favorite:
            params = {
                "device_platform": "webapp",
                "aid": "6383",
                "channel": "channel_pc_web",
                "sec_user_id": self.sec_user_id,
                "max_cursor": self.cursor,
                "min_cursor": "0",
                "whale_cut_token": "",
                "cut_version": "1",
                "count": "18",
                "publish_video_strategy_type": "2",
                "pc_client_type": "1",
                "version_code": "170400",
                "version_name": "17.4.0",
                "cookie_enabled": "true",
                "platform": "PC",
                "downlink": "10",
            }
        else:
            params = {
                "device_platform": "webapp",
                "aid": "6383",
                "channel": "channel_pc_web",
                "sec_user_id": self.sec_user_id,
                "max_cursor": str(self.cursor),
                "locate_query": "false",
                "show_live_replay_strategy": "1",
                "need_time_list": "0",
                "time_list_query": "0",
                "whale_cut_token": "",
                "cut_version": "1",
                "count": "18",
                "publish_video_strategy_type": "2",
                "pc_client_type": "1",
                "version_code": "170400",
                "version_name": "17.4.0",
                "cookie_enabled": "true",
                "platform": "PC",
                "downlink": "10",
            }
        self.deal_url_params(params)
        if not (
                data := self.send_request(
                    api,
                    params=params)):
            print("获取账号作品数据失败")
            return False
        return data

    def generate_temp_data(self):
        temp_data = timestamp()
        print(f"获取账号昵称失败，本次运行将临时使用 {temp_data} 作为账号昵称和 UID")
        temp_dict = {
            "author": {
                "nickname": temp_data,
                "uid": temp_data,
            }
        }
        self.response.append(temp_dict)

    def summary_works(self):
        return len(self.response)
